package tt.dz.egobus.servicemanager.entities;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.validator.constraints.NotBlank;
import tt.dz.egobus.base.entity.BaseEntity;
import tt.dz.egobus.vo.KV;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

import static tt.dz.egobus.servicemanager.entities.Bus.BusTypeEnum.*;

/**
 * @author Anson
 * @date 17-3-16
 * @name
 * @since 1.0.1
 */
@Entity
@Table(name = "bus", schema = "servicemanager")
public class Bus extends BaseEntity {

    private static final long serialVersionUID = 4280345240241426087L;

    public static final KV<String, String> BUS_TYPE_ALIAS = new KV<>("b", "busType");

    static {
        List<KV<String, String>> aliaseList = new ArrayList<KV<String, String>>(1);
        aliaseList.add(BUS_TYPE_ALIAS);
        Bus.ALIAS_LIST.put(Bus.class, aliaseList);
    }


    /**
     * 车辆状态
     */
    public static enum BusTypeEnum {

        NOT_ACTIVE(0), NOT_USE(1), USE(2), EXCEPTION(3), REPAIR(4), BROKEN(-1);

        private int status;

        BusTypeEnum(int status) {
            this.status = status;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        public static BusTypeEnum getBusType(int status) {
            for (BusTypeEnum type : BusTypeEnum.values()) {
                if (type.getStatus() == status) {
                    return type;
                }
            }
            return null;
        }
    }


    /**
     * @author Anson
     * @date 17-5-15
     * @name 获取存在当前异常情况下可以修改状态的车辆状态集合
     * 在处于异常,维修,以及报废情况下,可以不需要关注异常状态
     * @since 1.0.4
     */
    public static int[] getAbleUpdateExcludeBusCodeAlertExcept() {
        return new int[]{BusTypeEnum.EXCEPTION.getStatus(), BusTypeEnum.REPAIR.getStatus(), BusTypeEnum.BROKEN.getStatus()};
    }


    /**
     * 判断是否可以绑定服务
     * 当前只能处于异常或者损坏了之后并且当前车辆正在使用中，不能注册服务
     *
     * @return
     */
    public boolean isAbleBindRegister() {
        return this.getStatus() != USE.getStatus()
                && this.getStatus() != EXCEPTION.getStatus()
                && this.getStatus() != BROKEN.getStatus();
    }

    /**
     * 是否可以解绑车辆注册服务
     *
     * @return
     */
    public boolean isAbleUnbingRegister() {
        return this.getStatus() != USE.getStatus();
    }

    /**
     * 设置绑定从未激活到未使用
     */
    public void setUnRegisterStatus() {
        this.setStatus(NOT_ACTIVE.getStatus());
    }

    /**
     * 设置绑定从未激活到未使用
     */
    public void setBindStatus() {
        this.setStatus(NOT_USE.getStatus());
    }

    /**
     * 设置未使用状态
     */
    public void setNotUse() {
        this.setStatus(NOT_USE.getStatus());
    }

    /**
     * 设置未使用状态
     */
    public void setNoActive() {
        this.setStatus(NOT_ACTIVE.getStatus());
    }

    /**
     * 确信当前是没有被使用
     *
     * @return
     */
    public boolean assertNotUsed() {
        return this.getStatus() == NOT_USE.getStatus();
    }

    /**
     * 确信当前是没有激活
     *
     * @return
     */
    public boolean assertNotActive() {
        return this.getStatus() == NOT_ACTIVE.getStatus();
    }

    /**
     * 确信当前是处于使用中
     *
     * @return
     */
    public boolean assertUsed() {
        return this.getStatus() == USE.getStatus();
    }

    /**
     * 确信当前是处于异常中
     *
     * @return
     */
    public boolean assertException() {
        return this.getStatus() == EXCEPTION.getStatus();
    }

    /**
     * 确信当前是处于维修中
     *
     * @return
     */
    public boolean assertRepair() {
        return this.getStatus() == REPAIR.getStatus();
    }

    /**
     * 确信当前是处于报废中
     *
     * @return
     */
    public boolean assertBroken() {
        return this.getStatus() == BROKEN.getStatus();
    }

    /**
     * 车牌
     */
    @Column(name = "car_no", length = 10)
    @NotBlank(message = "车牌不能为空")
    private String carNo;

    /**
     * 车辆状态
     * 车辆状态 0未激活，1：未使用,2：已经使用，3：异常，4：维修，-1：报废
     */
    @Column(length = 10)
    private int status = 0;

    /**
     * 当前关联的车型
     */
    @Column(name = "bus_type_id")
    @NotNull(message = "车型不能为空")
    private String busTypeId;

    @ManyToOne(targetEntity = BusType.class, fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name = "bus_type_id", insertable = false, updatable = false)
    private BusType busType;

    public Bus(String carNo, int status) {
        this.carNo = carNo;
        this.status = status;
    }

    public Bus() {

    }

    public String getBusTypeId() {
        return busTypeId;
    }

    public void setBusTypeId(String busTypeId) {
        this.busTypeId = busTypeId;
    }

    public BusType getBusType() {
        return busType;
    }

    public void setBusType(BusType busType) {
        this.busType = busType;
    }

    public String getCarNo() {
        return carNo;
    }

    public void setCarNo(String carNo) {
        this.carNo = carNo;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bus)) return false;

        Bus bus = (Bus) o;

        if (getStatus() != bus.getStatus()) return false;
        if (getCarNo() != null ? !getCarNo().equals(bus.getCarNo()) : bus.getCarNo() != null) return false;
        return getBusTypeId() != null ? getBusTypeId().equals(bus.getBusTypeId()) : bus.getBusTypeId() == null;

    }

    @Override
    public int hashCode() {
        int result = getCarNo() != null ? getCarNo().hashCode() : 0;
        result = 31 * result + getStatus();
        result = 31 * result + (getBusTypeId() != null ? getBusTypeId().hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Bus{" +
                "carNo='" + carNo + '\'' +
                ", status=" + status +
                ", busTypeId='" + busTypeId + '\'' +
                ", busType=" + busType +
                '}';
    }
}
